
#include "precompiled.h"
#include "nativeplugin.h"
#include "helper.h"
#include "windowsmanager.h"
#include <extensions/application.h>
#include <scripting/system/io/file.h>
#include "script/contextimpl.h"

using Optra::Extensions::ContextPtr;

class NativePluginPrivate{
public:
    NativePluginPrivate() {}
    ~NativePluginPrivate() {}
    ContextPtr ctx;
    Optra::Extensions::Plugin::Type type;
    QFileInfo fileInfo;
    Optra::Extensions::Application* interface;
};

NativePlugin::NativePlugin(Optra::Extensions::Plugin::Type type, const ContextPtr& ctx, const QFileInfo& info, Opl::Core::EntityObject *parent) :
    Optra::Extensions::Plugin(type, ctx, 0), O_PRIVATE_CREATE(NativePlugin)
{
    O_D(NativePlugin);
    d->ctx = ctx;
    d->fileInfo = info;
    d->type = type;
    d->interface = 0;
}

NativePlugin::~NativePlugin()
{
    O_PRIVATE_DELETE;
}

void NativePlugin::registerObject(const QString& name, Opl::Core::EntityObject* object, const QString& package/* = ""*/)
{
    O_D(NativePlugin);
}

bool NativePlugin::initialize()
{
    O_D(NativePlugin);
    LI.Debug() << "Loading Native Extension:" << d->fileInfo.absoluteFilePath();
    QPluginLoader pluginLoader(d->fileInfo.absoluteFilePath());
    QObject *plugin = pluginLoader.instance();
    if (plugin){
        d->interface = qobject_cast<Optra::Extensions::Application *>(plugin);
        if (!d->interface){
            LI.Warning() << "Invalid plugind interface";
            return false;
        }

        //ctx->setInterface(interface);
        //        LI.Debug()
        //                << "\tName: "
        //                << interface->name()
        //                << " Context: " << ctx->toString();

        //interface->setContext(ctx);
        d->interface->Setup(d->type, d->ctx);
        Engine::instance()->windowsManager()->addWindow(d->interface->mainWindow());
        return true;
    }else{
        LI.Warning() << "Failed loading: " << d->ctx->toString() << " error:" << pluginLoader.errorString();
        return false;
    }
    return true;
}

void NativePlugin::start()
{
    O_D(NativePlugin);


    //Engine::instance()->windowsManager()->addItem(d->mainItem());
}

bool NativePlugin::registerClass(Opl::Scripting::System::IO::File* file)
{
    Q_ASSERT(file);
    LI.Info() << "Registering class, from QML:" << file->name();

    QString fn = context()->rootDir().absoluteFilePath(file->name());
    QFileInfo fi(fn);
    Engine::instance()->windowsManager()->registerQMLControl(fi.baseName(), fn);
    return false;
}


void NativePlugin::stop()
{
    O_D(NativePlugin);
    Engine::instance()->windowsManager()->removeWindow(d->interface->mainWindow());
}

void NativePlugin::reload()
{
    O_D(NativePlugin);
    stop();
    start();
}
